package gaoji;

/**
 * 多线程共用同一资源，生产消费问题，管程法
 */

public class TestNotify {
    public static void main(String[] args) {
        SynContainer synContainer = new SynContainer();
        new Product(synContainer).start();
        new Customs(synContainer).start();
    }
}

class Product extends Thread {
    SynContainer synContainer;

    public Product(SynContainer synContainer) {
        this.synContainer = synContainer;
    }

    @Override
    public void run() {
        for (int i = 1; i <= 10; i++) {
            synContainer.push(new Goods(i));
            System.out.println("生产了第" + i + "个产品");
        }
    }
}

class Customs extends Thread {
    SynContainer synContainer;

    public Customs(SynContainer synContainer) {
        this.synContainer = synContainer;
    }

    @Override
    public void run() {
        for (int i = 1; i <= 10; i++) {
            System.out.println("消费了第" + synContainer.pop().id + "个产品");
        }
    }
}

//缓冲区
class SynContainer {
    //容器大小
    Goods[] goods = new Goods[10];
    //计数
    int count = 0;

    //生产者放入产品
    public synchronized void push(Goods good) {
        if (count == goods.length) {
            //容器满，通知消费，生产等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //放入产品
        goods[count] = good;
        count++;
        //通知消费
        this.notifyAll();
    }

    //消费者取出产品
    public synchronized Goods pop() {
        if (count == 0) {
            //没有产品，通知生产，消费等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //消费
        count--;
        Goods good = goods[count];
        //消费完，通知生产
        this.notifyAll();
        return good;
    }
}

class Goods {
    int id;

    public Goods(int id) {
        this.id = id;
    }
}